home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MACD 5
/
MACD 5.bin
/
workbench
/
libs
/
unixlib.lha
/
unix
/
test
/
exec_test3.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-07-07
|
3KB
|
136 lines
/* test program for exec() in unix.lib
*
* Launches as a child a program specified on the command line. The child
* must perform input and output from its standard I/O. Precisely it must
* request something in input and produce output conseguently.
* The program: 1) attaches the write end of a pipe to the standard output of
* the child and reads its output from the read end; 2) attaches the read
* end of another pipe to the standard input of the child and passes input
* to it from the write end.
*/
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <dos/dos.h>
#include <proto/dos.h>
typedef unsigned char bool;
#define FALSE 0
#define TRUE 1
char *program;
void
LogFatal(char *x0, char *x1)
{
extern char *sys_errlist[];
static bool entered = FALSE;
if (entered)
return;
entered = TRUE;
fprintf(stderr, "%s: ", program);
if (errno)
fprintf(stderr, "%s: ", sys_errlist[ errno ]);
fprintf(stderr, x0,x1);
fprintf(stderr, " Stop.\n");
exit(20);
}
void
LogFatalI(char *s, int i)
{
/*NOSTRICT*/
LogFatal(s, (char *)i);
}
int fd;
void
sendc(int sig)
{ /* if the child doesn't output the wanted */
write(fd, ">", 1); /* char '>' within the amount of time */
close(fd); /* specified in alarm(), we do it for him */
} /* so as to non block the parent */
int
main(int ac, char **av)
{
int pid, status;
int std_in[2];
int std_out[2];
int c;
char *comm;
char *argv[3];
FILE *infp;
FILE *outfp;
if (ac == 1 || ac > 3) {
fprintf(stderr, "Usage: %s test-program [argument]\n", av[0]);
exit(EXIT_FAILURE);
}
program = av[0];
comm = av[1];
argv[0] = av[1];
if (ac == 3)
argv[1] = av[2];
else
argv[1] = NULL;
argv[2] = NULL;
/* The exec() function in unix.lib starts a child process. */
/* It is possible to give the child input, output, current */
/* dir and stack different from the parent. If the input */
/* or the output of the child are changed, they are closed */
/* after the child exits. Exec() returns the child pid. */
if (pipe(std_in) != 0 || pipe(std_out) != 0)
LogFatal("Cannot get a pipe.", "");
if (!(infp = fdopen(std_out[0], "r")) ||
!(outfp = fdopen(std_in[1], "w")))
LogFatal("Cannot attach a stream to pipe.", "");
/* fd is used in sendc() to provide the '>' char */
fd = dup(std_out[1]);
pid = exec(comm, argv, std_in[0], std_out[1], NULL, 4096);
if (pid < 0)
LogFatal("Cannot exec %s.", comm);
printf("child request: ");
signal(SIGALRM, sendc);
alarm(2);
while((c = getc(infp)) != '>')
putchar(c);
alarm(0);
fflush(stdout);
while((c = getchar()) != '\n')
putc(c, outfp);
putc('\n', outfp);
fclose(outfp);
printf("child response: ");
while((c = getc(infp)) != '\n')
putchar(c);
putchar('\n');
fclose(infp);
/* Simply wait child completion */
if (wait(&status) > 0) {
if (WIFSIGNALED(status))
LogFatalI("Signal %d.", WTERMSIG(status));
if (WIFEXITED(status) && WEXITSTATUS(status))
LogFatalI("Exit code %d.", WEXITSTATUS(status));
}
return(WEXITSTATUS(status));
}